package com.example.domain.repository;

import com.example.domain.entity.Product;
import com.example.domain.entity.enums.ProductStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

/**
 * 商品Repository
 * 
 * @author Means
 * @since 2025-10-27
 */
@Repository
public interface ProductRepository extends JpaRepository<Product, String> {
    
    // ========== 基础查询 ==========
    // 注：基础List查询方法已删除，统一使用分页查询或自定义@Query方法
    
    // ========== 模糊查询 ==========
    
    /**
     * 根据名称模糊查询未删除的商品（忽略大小写）
     * 
     * @param keyword 关键字
     * @return 商品列表
     */
    @Query("SELECT p FROM Product p WHERE LOWER(p.name) LIKE LOWER(CONCAT('%', :keyword, '%')) AND p.isDeleted = false")
    List<Product> findByNameContainingIgnoreCaseAndIsDeletedFalse(@Param("keyword") String keyword);
    
    /**
     * 根据名称模糊搜索未删除的商品（分页）
     * 
     * @param keyword 关键字
     * @param pageable 分页参数
     * @return 商品分页结果
     */
    @Query("SELECT p FROM Product p WHERE LOWER(p.name) LIKE LOWER(CONCAT('%', :keyword, '%')) AND p.isDeleted = false")
    Page<Product> searchByNameContaining(@Param("keyword") String keyword, Pageable pageable);
    
    // ========== 分页查询 ==========
    
    /**
     * 分页查询未删除的商品
     * 用于列表页的无条件查询
     * 
     * @param isDeleted 是否删除（通常传false）
     * @param pageable 分页参数
     * @return 商品分页结果
     */
    Page<Product> findByIsDeleted(Boolean isDeleted, Pageable pageable);
    
    /**
     * 根据状态分页查询未删除的商品
     * 用于按状态筛选商品列表
     * 
     * @param status 商品状态
     * @param isDeleted 是否删除（通常传false）
     * @param pageable 分页参数
     * @return 商品分页结果
     */
    Page<Product> findByStatusAndIsDeleted(ProductStatus status, Boolean isDeleted, Pageable pageable);
    
    /**
     * 根据分类分页查询未删除的商品
     * 用于按分类筛选商品列表
     * 
     * @param category 商品分类
     * @param isDeleted 是否删除（通常传false）
     * @param pageable 分页参数
     * @return 商品分页结果
     */
    Page<Product> findByCategoryAndIsDeleted(String category, Boolean isDeleted, Pageable pageable);
    
    /**
     * 根据状态和分类分页查询未删除的商品
     * 用于同时按状态和分类筛选商品列表
     * 
     * @param status 商品状态
     * @param category 商品分类
     * @param isDeleted 是否删除（通常传false）
     * @param pageable 分页参数
     * @return 商品分页结果
     */
    Page<Product> findByStatusAndCategoryAndIsDeleted(ProductStatus status, String category, Boolean isDeleted, Pageable pageable);
    
    // ========== 自定义查询 ==========
    
    /**
     * 查询所有上架商品（已上架且未删除）
     * 用于前端商品列表展示
     * 
     * @return 商品列表（按创建时间倒序）
     */
    @Query("SELECT p FROM Product p WHERE p.status = 'ACTIVE' AND p.isDeleted = false ORDER BY p.createdAt DESC")
    List<Product> findActiveProducts();
    
    /**
     * 根据ID查询未删除的商品（推荐使用）
     * 
     * @param id 商品ID
     * @return 商品对象
     */
    @Query("SELECT p FROM Product p WHERE p.id = :id AND p.isDeleted = false")
    Optional<Product> findByIdAndNotDeleted(@Param("id") String id);
    
    /**
     * 根据ID批量查询未删除的商品
     * 用于批量查询商品信息
     * 
     * @param ids 商品ID列表
     * @return 商品列表
     */
    @Query("SELECT p FROM Product p WHERE p.id IN :ids AND p.isDeleted = false")
    List<Product> findByIdsAndNotDeleted(@Param("ids") List<String> ids);
    
    /**
     * 软删除商品（逻辑删除）
     * 将商品标记为已删除，而非物理删除
     * 
     * @param id 商品ID
     */
    @Modifying
    @Query("UPDATE Product p SET p.isDeleted = true WHERE p.id = :id")
    void softDelete(@Param("id") String id);
    
    /**
     * 根据状态查询未删除的商品（List返回）
     * 用于不需要分页的场景（如按状态获取所有商品）
     * 
     * @param status 商品状态
     * @return 商品列表
     */
    @Query("SELECT p FROM Product p WHERE p.status = :status AND p.isDeleted = false")
    List<Product> findByStatusAndIsDeletedFalse(@Param("status") ProductStatus status);
    
    /**
     * 根据状态和分类查询未删除的商品（List返回）
     * 用于按分类筛选特定状态的商品（如获取某分类下的所有上架商品）
     * 
     * @param status 商品状态
     * @param category 商品分类
     * @return 商品列表
     */
    @Query("SELECT p FROM Product p WHERE p.status = :status AND p.category = :category AND p.isDeleted = false")
    List<Product> findByStatusAndCategoryAndIsDeletedFalse(@Param("status") ProductStatus status, @Param("category") String category);
}


